package com.liuyc.lib.ui.xrecycleview

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.drawable.AnimationDrawable
import android.os.Handler
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.liuyc.lib.ui.R

class CustomRefreshHeader @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr), CustomBaseRefreshHeader {
    private var mContext: Context? = null
    private var animationDrawable: AnimationDrawable? = null
    private var msg: TextView? = null
    private var mState = CustomBaseRefreshHeader.STATE_NORMAL
    private var mMeasuredHeight = 0
    private var mContainer: LinearLayout? = null

    init {
        mContext = context
        initView()
    }

    private fun initView() {
        LayoutInflater.from(mContext).inflate(R.layout.refresh_header, this)
        val img = findViewById<View>(R.id.img) as ImageView
        animationDrawable = img.drawable as AnimationDrawable
        if (animationDrawable!!.isRunning) {
            animationDrawable!!.stop()
        }
        msg = findViewById<View>(R.id.msg) as TextView
        measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        mMeasuredHeight = measuredHeight
        gravity = Gravity.CENTER_HORIZONTAL
        mContainer = findViewById<View>(R.id.container) as LinearLayout
        mContainer!!.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, 0)
        this.layoutParams = LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
    }


    override fun onMove(delta: Float) {
        if (getVisiableHeight() > 0 || delta > 0) {
            setVisiableHeight(delta.toInt() + getVisiableHeight())
            if (mState <= CustomBaseRefreshHeader.STATE_RELEASE_TO_REFRESH) { // 未处于刷新状态，更新箭头
                if (getVisiableHeight() > mMeasuredHeight) {
                    setState(CustomBaseRefreshHeader.STATE_RELEASE_TO_REFRESH)
                } else {
                    setState(CustomBaseRefreshHeader.STATE_NORMAL)
                }
            }
        }
    }

    private fun setState(state: Int) {
        if (state == mState) return
        when (state) {
            CustomBaseRefreshHeader.STATE_NORMAL -> {
                if (animationDrawable!!.isRunning) {
                    animationDrawable!!.stop()
                }
                msg!!.setText(R.string.listview_header_hint_normal)
            }
            CustomBaseRefreshHeader.STATE_RELEASE_TO_REFRESH -> if (mState != CustomBaseRefreshHeader.STATE_RELEASE_TO_REFRESH) {
                if (!animationDrawable!!.isRunning) {
                    animationDrawable!!.start()
                }
                msg!!.setText(R.string.listview_header_hint_release)
            }
            CustomBaseRefreshHeader.STATE_REFRESHING -> msg!!.setText(R.string.refreshing)
            CustomBaseRefreshHeader.STATE_DONE -> msg!!.setText(R.string.refresh_done)
            else -> {
            }
        }
        mState = state
    }

    override fun releaseAction(): Boolean {
        var isOnRefresh = false
        val height = getVisiableHeight()
        if (height == 0) // not visible.
            isOnRefresh = false
        if (getVisiableHeight() > mMeasuredHeight && mState < CustomBaseRefreshHeader.STATE_REFRESHING) {
            setState(CustomBaseRefreshHeader.STATE_REFRESHING)
            isOnRefresh = true
        }
        // refreshing and header isn't shown fully. do nothing.
        if (mState == CustomBaseRefreshHeader.STATE_REFRESHING && height <= mMeasuredHeight) {
            //return;
        }
        var destHeight = 0 // default: scroll back to dismiss header.
        // is refreshing, just scroll back to show all the header.
        if (mState == CustomBaseRefreshHeader.STATE_REFRESHING) {
            destHeight = mMeasuredHeight
        }
        smoothScrollTo(destHeight)
        return isOnRefresh
    }

    override fun refreshComplete() {
        setState(CustomBaseRefreshHeader.STATE_DONE)
        Handler().postDelayed({ reset() }, 500)
    }

    fun reset() {
        smoothScrollTo(0)
        setState(CustomBaseRefreshHeader.STATE_NORMAL)
    }

    private fun smoothScrollTo(destHeight: Int) {
        val animator = ValueAnimator.ofInt(getVisiableHeight(), destHeight)
        animator.setDuration(300).start()
        animator.addUpdateListener { animation -> setVisiableHeight(animation.animatedValue as Int) }
        animator.start()
    }

    private fun setVisiableHeight(height: Int) {
        var height = height
        if (height < 0) height = 0
        //       `
        val lp = LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0)
        lp.height = height
        mContainer!!.layoutParams = lp
    }

    override fun getVisiableHeight(): Int {
        return mContainer!!.height
    }

    fun getState(): Int {
        return mState
    }
}